/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkTDynamicHash_DEFINED
#define SkTDynamicHash_DEFINED

// This is now a simple API wrapper around THashTable<T*>;
// please just use SkTHash{Map,Set,Table} directly for new code.
#include "src/core/SkTHash.h"

// Traits requires:
//   static const Key& GetKey(const T&) { ... }
//   static uint32_t Hash(const Key&) { ... }
// We'll look on T for these by default, or you can pass a custom Traits type.
template <typename T, typename Key, typename Traits = T> class SkTDynamicHash {
public:
    SkTDynamicHash() {}

    // It is not safe to call set() or remove() while iterating with either foreach().
    // If you mutate the entries be very careful not to change the Key.

    template <typename Fn> // f(T*)
    void foreach (Fn &&fn)
    {
        fTable.foreach ([&](T **entry) { fn(*entry); });
    }
    template <typename Fn> // f(T) or f(const T&)
    void foreach (Fn &&fn) const
    {
        fTable.foreach ([&](T *entry) { fn(*entry); });
    }

    int count() const
    {
        return fTable.count();
    }

    size_t approxBytesUsed() const
    {
        return fTable.approxBytesUsed();
    }

    T *find(const Key &key) const
    {
        return fTable.findOrNull(key);
    }

    void add(T *entry)
    {
        fTable.set(entry);
    }
    void remove(const Key &key)
    {
        fTable.remove(key);
    }

    void rewind()
    {
        fTable.reset();
    }
    void reset()
    {
        fTable.reset();
    }

private:
    struct AdaptedTraits {
        static const Key &GetKey(T *entry)
        {
            return Traits::GetKey(*entry);
        }
        static uint32_t Hash(const Key &key)
        {
            return Traits::Hash(key);
        }
    };
    skia_private::THashTable<T *, Key, AdaptedTraits> fTable;
};

#endif
